/*
 * Copyright 2021 Hannes Dorfmann.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.hannesdorfmann.mosby3.sample.mvi.slice;

import com.hannesdorfmann.mosby3.mvi.MviAbilitySlice;
import com.hannesdorfmann.mosby3.sample.mvi.MyApplication;
import com.hannesdorfmann.mosby3.sample.mvi.ResourceTable;
import com.hannesdorfmann.mosby3.sample.mvi.businesslogic.interactor.details.ProductDetailsViewState;
import com.hannesdorfmann.mosby3.sample.mvi.businesslogic.model.Product;
import com.hannesdorfmann.mosby3.sample.mvi.dependencyinjection.DependencyInjection;
import com.hannesdorfmann.mosby3.sample.mvi.util.ImageUtils;
import com.hannesdorfmann.mosby3.sample.mvi.view.detail.ProductDetailsPresenter;
import com.hannesdorfmann.mosby3.sample.mvi.view.detail.ProductDetailsView;
import com.hannesdorfmann.mosby3.sample.mvi.view.widge.CirleProgressImg;
import com.jakewharton.rxbinding2.component.RxComponent;
import io.reactivex.Observable;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;
import ohos.agp.components.element.PixelMapElement;
import ohos.global.resource.NotExistException;
import ohos.global.resource.Resource;

import java.io.IOException;
import java.util.Locale;

public class ProductDetailsAbilitySlice extends MviAbilitySlice<ProductDetailsView, ProductDetailsPresenter>
        implements ProductDetailsView {

    public static final String KEY_PRODUCT_ID = "productId";
    private Product product;
    private boolean isProductInshoppingCart = false;
    private Observable<Boolean> fabClickObservable;
    private int productId;

    Text errorView;
    CirleProgressImg loadingView;
    DependentLayout detailsView;
    Text price;
    Text description;
    Button fab;
    Image backdrop;

    ComponentContainer rootView;


    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_activity_product_detail);
        productId = (int) intent.getParams().getParam(KEY_PRODUCT_ID);

        errorView = (Text) findComponentById(ResourceTable.Id_errorView);
        loadingView = (CirleProgressImg) findComponentById(ResourceTable.Id_loadingView);
        detailsView = (DependentLayout) findComponentById(ResourceTable.Id_detailsView);
        price = (Text) findComponentById(ResourceTable.Id_price);
        description = (Text) findComponentById(ResourceTable.Id_description);
        fab = (Button) findComponentById(ResourceTable.Id_fab);
        backdrop = (Image) findComponentById(ResourceTable.Id_backdrop);
        rootView = (ComponentContainer) findComponentById(ResourceTable.Id_root);

        fabClickObservable = RxComponent.clicks(fab).share().map(ignored -> true);
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }


    @Override
    public ProductDetailsPresenter createPresenter() {
        return MyApplication.getDependencyInjection(this).newProductDetailsPresenter();
    }

    @Override
    public Observable<Integer> loadDetailsIntent() {
        return Observable.just(productId);
    }

    @Override
    public Observable<Product> addToShoppingCartIntent() {
        return fabClickObservable.filter(item -> product != null)
                .filter(item -> !isProductInshoppingCart)
                .map(item -> product);
    }

    @Override
    public Observable<Product> removeFromShoppingCartIntent() {
        return fabClickObservable.filter(item -> product != null)
                .filter(item -> isProductInshoppingCart)
                .map(item -> product);
    }

    @Override
    public void render(ProductDetailsViewState state) {

        if (state instanceof ProductDetailsViewState.LoadingState) {
            renderLoading();
        } else if (state instanceof ProductDetailsViewState.DataState) {
            renderData((ProductDetailsViewState.DataState) state);
        } else if (state instanceof ProductDetailsViewState.ErrorState) {
            renderError();
        } else {
            throw new IllegalStateException("Unknown state " + state);
        }
    }

    private void renderError() {
        errorView.setVisibility(Component.VISIBLE);
        loadingView.setVisibility(Component.HIDE);
        detailsView.setVisibility(Component.HIDE);
    }

    private void renderData(ProductDetailsViewState.DataState state) {
        errorView.setVisibility(Component.HIDE);
        loadingView.setVisibility(Component.HIDE);
        detailsView.setVisibility(Component.VISIBLE);

        isProductInshoppingCart = state.getDetail().isInShoppingCart();
        product = state.getDetail().getProduct();
        price.setText("Price: $" + String.format(Locale.US, "%.2f", product.getPrice()));
        description.setText(product.getDescription());


        Resource bgResource = null;
        Resource btnBgResource = null;
        try {
            bgResource = getResourceManager().getResource(ResourceTable.Media_ic_in_shopping_cart);
            btnBgResource = getResourceManager().getResource(ResourceTable.Media_ic_add_shopping_cart);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotExistException e) {
            e.printStackTrace();
        }
        PixelMapElement pixBg = new PixelMapElement(bgResource);
        PixelMapElement pixBtnBg = new PixelMapElement(btnBgResource);


        if (isProductInshoppingCart) {
            fab.setBackground(pixBg);
        } else {
            fab.setBackground(pixBtnBg);
        }

        ImageUtils.load(this, backdrop, DependencyInjection.BASE_IMAGE_URL + product.getImage());
    }

    private void renderLoading() {
        errorView.setVisibility(Component.HIDE);
        loadingView.setVisibility(Component.VISIBLE);
        detailsView.setVisibility(Component.HIDE);
    }

}
